<?php
if (!defined('XOOPS_ROOT_PATH')) exit;

class links_Link
{
	var $controller_name;

	var $orderby          = '' ;
	var $where            = '';
	var $single_view      = FALSE;
	var $save_items       = array();
	var $save_description = NULL;
	var $status_code      = '';
	var $block_capture    = FALSE;

	function links_Link()
	{
	}

	function getCount()
	{
		$db =& Database::getInstance();
		$sql = "SELECT count(*) FROM " . $this->table_links . " WHERE " . $this->where;
//var_dump($sql);
		$temp_num = $db->fetchRow($db->query($sql));
		return intval($temp_num[0]);
	}

	function getAllLid()
	{
		$db =& Database::getInstance();
		$sql = "SELECT `lid` FROM `". $this->table_links ."` WHERE `date`<". time() ." AND `status`>0 ORDER BY `date` DESC";

		$result = $db->query($sql) ;
		$returnrow = array();
		while( $row = $db->fetchArray($result) ){
			$returnrow[] = intval($row['lid']) ;
		}
		return $returnrow ;
	}

	function getDataByLid($lid = NULL, $single_view = FALSE)
	{
		$this->clearWhere();
		$this->_clear_order();

		$this->single_view = $single_view;
		$this->setWhere('l.lid', $lid, '=');
		if (! $this->isadmin){
			$this->setWhere('status', 0, '>');
		}
		$link_arr = $this->getDatas();

		if (count($link_arr) != 1) {
			$link = FALSE;
		} else {
			$link = $link_arr[0];
		}

		return $link;
	}

	function getDatas($limit = NULL, $offset = NULL)
	{
		global $xoopsConfig ;
		$myts =& MyTextSanitizer::getInstance();
		$db =& Database::getInstance();

		$sql = "SELECT * FROM ". $this->table_links ." l, ". $this->table_text ." t WHERE ". $this->where ." AND l.lid=t.lid ". $this->orderby ;
//var_dump($sql);//exit;
		$datas = array() ;
		$result = $db->query($sql, $limit, $offset) ;

		while( $row = $db->fetchArray($result)) {
			$adminlink =  ( ($this->edit_perm && $row['submitter']==$this->uid) || $this->isadmin ) ? TRUE : FALSE ;
			$votestring = ( $row['votes'] == 1 ) ? _MD_ONEVOTE : sprintf(_MD_NUMVOTES,$row['votes']) ;

			//CID
			$sort_cid_arr = $this->_cid_array_from_cid_text($row['cid']);
			unset($path);
			for( $i=0; $i<count($sort_cid_arr); $i++ ){
				$path[$i] = $this->Categories->getPathFromId($sort_cid_arr[$i]) ;//TODO
			}

			$url =  !empty($row['url']) ? links_urlCheckReplace( $row['url'] ) : "" ;
			$murl = !empty($row['murl']) ? links_urlCheckReplace( $row['murl'] ) : "" ;
			$submitter_name = empty($row['guestname']) ? $this->getUnameFromUid($row['submitter']) 
									: htmlspecialchars($row['guestname'], ENT_QUOTES, _CHARSET) ;

			//mail
			$mail_subject = sprintf(_MD_INTRESTLINK,$xoopsConfig['sitename']);
			$mail_body = sprintf(_MD_INTLINKFOUND,$xoopsConfig['sitename']).' : '. $this->makeUrl('index', 'item', array('lid'=>$row['lid']), FALSE);

			if ($this->controller_name == 'edit') {
				$description = $myts->makeTareaData4Edit($row['description']);
				$title = $myts->makeTareaData4Edit($row['title']);
			} else {
				$description = $myts->makeTareaData4Show($row['description'],0);
				$title = htmlspecialchars($row['title'], ENT_QUOTES, _CHARSET);
			}

			//Capture Check
			$capture = FALSE;
			if (($this->screen_shot == 1 && $this->screenshot_cache_time > 0 
					&& ! in_array($this->controller_name, array('rss', 'ranking', 'adult', 'future', 'admin_approval', 'broken', 'request', 'admin_broken', 'admin_request')) ) || $this->block_capture) {
				$capture = $this->_check_cache_file($row['lid'], $url, $row['date']);
			}

			$datas[] = array(
				'lid'           => $row['lid'] ,
				'cid'           => $sort_cid_arr ,
				'category'      => $path ,
				'title'         => links_urlCheckReplace($title, FALSE),
				'new'           => $this->_new_link_check($row['date'], $row['status']),
				'pop'           => $this->_pop_check($row['hits']),
				'url'           => htmlspecialchars($url, ENT_QUOTES, _CHARSET),
				'murl'          => htmlspecialchars($murl, ENT_QUOTES, _CHARSET),
				'murl_qr'       => str_replace('&amp;', '&', htmlspecialchars($murl, ENT_QUOTES, _CHARSET)),
				'submitter'     => intval($row['submitter']) ,
				'submitterName' => $submitter_name ,
				'guestname'     => htmlspecialchars($row['guestname'], ENT_QUOTES, _CHARSET) ,
				'status'        => intval($row['status']) ,
				'date'          => intval($row['date']) ,
				'hits'          => intval($row['hits']) ,
				'rating'        => floatval($row['rating']) ,
				'votes'         => $votestring ,
				'votes_num'     => intval($row['votes']) ,
				'access'        => intval($row['access']) ,
				'adult'         => intval($row['adult']) ,
				'ip'            => htmlspecialchars($row['ip'], ENT_QUOTES, _CHARSET) ,
				'description'   => $description ,
				'adminlink'     => $adminlink ,
				'mail_subject'  => rawurlencode($mail_subject) ,
				'mail_body'     => rawurlencode($mail_body) ,
				'capture'       => $capture,
				'link_url'      => $this->makeUrl('index', 'item', array('lid' => $row['lid'])),
			);
		}

		return $datas;
	}

	function setWhere($key, $val, $op = '', $or_and = 'AND')
	{
		if (!empty($this->where)) {
			$this->where .= strtoupper($or_and)=='AND' ? 'AND': 'OR';
		}
		if (!in_array($op, array('=', '<', '>', '<=', '>=', '<>', 'LIKE'))) {
			$op = '';
		}
		$this->where .= " ". mysql_real_escape_string($key) ." ". $op ." '". mysql_real_escape_string($val) ."' ";
	}

	function setRealWhere($where, $or_and = 'AND')
	{
//	var_dump($where);
		if (!empty($this->where)) {
			$this->where .= strtoupper($or_and)=='AND' ? 'AND': 'OR';
		}
		$this->where .= $where;
	}

	function clearWhere()
	{
		$this->where = '';
	}

	function setOrder( $order )
	{
		$this->orderby = "ORDER BY $order" ;
	}

	function _clear_order()
	{
		$this->order = '';
	}

	/** Insert
	 *
	**/
	function insert()
	{
		$this->_get_POST_data();
		$this->_basic_post_data_check('insert');

		//category
		$cidtext = $this->_for_save_cid_data($this->save_items['cid']);

		$this->save_items['cid']       = $cidtext;
		$this->save_items['submitter'] = $this->uid;
		$this->save_items['status']    = $this->post_approval ? 1 : 0;
		$this->save_items['ip']        = xoops_getenv("REMOTE_ADDR");
		$this->_save();

	//	$db =& Database::getInstance();
		$new_lid = $this->db->getInsertId();
		$sql = sprintf("INSERT INTO `%s` (`lid`, `description`) VALUES (%u, '%s')", 
					$this->table_text, 
					$new_lid, 
					mysql_real_escape_string($this->save_description)
				);
		$this->db->query($sql) or die("DB Error: INSERT link description");

		return TRUE;
	}

	function update($lid, $present_status)
	{
		$this->_get_POST_data();
		$this->_basic_post_data_check('update', $lid);

		//category
		$cidtext = $this->_for_save_cid_data($this->save_items['cid']);

		//status
		$status = FALSE ;
		if ($this->edit_approval) {
			if ($this->isadmin) {
				$status = ( $present_status == -3 || $present_status == 0 ) ? 1 : 2 ;//-3 : easypost
			} else {
				if ( $present_status == 1 || $present_status == 2 ) $status = 2 ;
			}
		} else {
			if ($present_status == 1 || $present_status == 2) $status = -1 ;
		}
		if ($status === FALSE) {
			$this->linksRedirectHeader($this->baseUrl(TRUE), 3, _NOPERM);
			exit;
		}

		// Force Capture Copy
		if ($this->screen_shot == 1 AND $this->screenshot_cache_time > 0 AND $_POST['force_copy'] == 1) {
			$this->_force_copy($lid, $this->save_items['url']);
		}

		//UPDATE
		$this->save_items['cid']    = $cidtext;
		$this->save_items['status'] = $status;
		$this->save_items['ip']     = xoops_getenv("REMOTE_ADDR");
		$this->_save($lid);

		$db =& Database::getInstance();
		$db->query("UPDATE ". $this->table_text .
			" SET `description`='". mysql_real_escape_string($this->save_description) .
			"' where `lid`=". $lid
		) or die( "DB Error: UPDATE link text" );

		return TRUE;
	}

	function _save($lid = NULL, $force = FALSE)
	{
		$this->db =& Database::getInstance();
		if (!empty($lid)) {
			// UPDATE
			$save_data = '';
			foreach ($this->save_items as $key => $val) {
				if (!empty($val) || $val === 0 || $key == 'url' || $key == 'murl') {// TODO
					if (!empty($save_data)) $save_data .= ", ";
					$save_data .= "`$key`='". mysql_real_escape_string($val) ."'";
				}
			}
			$sql = "UPDATE ". $this->table_links ." SET ". $save_data . " WHERE `lid`=". $lid;
			if ($force) {
				$this->db->queryF($sql) or die( "DB Error: UPDATE link [F]" );
			} else {
				$this->db->query($sql) or die( "DB Error: UPDATE link" );
			}
		} else {
			// INSERT
			$fields = $values = '';
			foreach ($this->save_items as $key => $val) {
				if (!empty($val) || $val === 0) {
					if (!empty($fields)) $fields .= ", ";
					$fields .= $key;
					if (!empty($values)) $values .= ", ";
					$values .= "'". mysql_real_escape_string($val) ."'";
				}
			}
			$sql = "INSERT INTO ". $this->table_links . " ( $fields ) VALUES ( $values )";
			if ($force) {
				$this->db->queryF($sql) or die( "DB Error: INSERT link [F]" );
			} else {
				$this->db->query($sql) or die( "DB Error: INSERT link" );
			}
		}

		return TRUE;
	} 

	function saveRating($lid, $rating, $votes)
	{
		$this->_clear_data();
		$this->save_items['rating'] = $rating;
		$this->save_items['votes']  = $votes;
		return $this->_save($lid);
	}

	function saveApproval($lid, $status)
	{
		$this->_clear_data();
		$this->save_items['status'] = $status;
		return $this->_save($lid);
	}

	function saveEasypost($cid, $ip, $url, $url_field)
	{
		$this->_clear_data();
		$this->save_items['cid']       = "[$cid]";
		$this->save_items['submitter'] = $this->uid;
		$this->save_items['title']     = _MD_EASYPOST_TITLE ." ({$url})";
		$this->save_items['status']    = -3;
		$this->save_items['ip']        = $ip;
		$this->save_items[$url_field]  = $url;
		$this->save_items['date']      = time();
		$this->_save();

		$db =& Database::getInstance();
		$new_lid = $db->getInsertId();
		$sql = "INSERT INTO ". $this->table_text ." (lid, description) VALUES ($new_lid, '')";
		$db->query($sql) or die( "DB Error: INSERT link description" );

		return;
	}

	function delete($lid)
	{
		$lid = intval($lid);
		$db =& Database::getInstance();

		if (!$this->del_approval) {
			$sql = "UPDATE ". $this->table_links ." SET status=-2, date=".time()." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE link request" );
		} else {
			//LINK
			$sql = "DELETE FROM ". $this->table_links ." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE link" );
			//TEXT
			$sql = "DELETE FROM ". $this->table_text ." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE text" );
			//RATING
			$sql = "DELETE FROM ". $db->prefix($this->mydirname . '_rating') ." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE votedata" );
			//BROKEN
			$sql = "DELETE FROM ". $db->prefix($this->mydirname . '_broken') ." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE broken" );
			//REQUEST
			$sql = "DELETE FROM ". $db->prefix($this->mydirname . '_request') ." WHERE lid=$lid";
			$db->query($sql) or die( "DB Error: DELETE request" );
		}

		return TRUE;
	}

	function makeOrderHtml($controller, $method, $order_by = 'date DESC', $submitter = 0, $cid = 0)
	{
		$asc_img = "<img src='". $this->myurl ."/images/asc.png' border='0' />";
		$desc_img = "<img src='". $this->myurl ."/images/desc.png' border='0' />";

		$args_plus1 = $args_plus2 = array();
		if ($submitter > 0) $args_plus1 = array_merge(array('uid'   => $submitter)/*, $args_plus*/) ;
		if ($cid > 0) $args_plus2 = array_merge(array('cid'   => $cid)/*, $args_plus*/) ;

		$title_img = $date_img = $rating_img = $hits_img = $access_img = '';
		list($field, $order) = explode(' ', $order_by);
		$img = strtolower($order) .'_img';
		$target = strtolower($field) .'_img';
		$$target = $$img ;
		
		$field_arr = array(0=>'title', 1=>'date', 2=>'access', 3=>'hits', 4=>'rating');
		$title_arr = array(0=>_MD_SITETITLE, 1=>_MD_LINKS_DATE, 2=>_MD_ACCESS, 3=>_MD_POPULARITY, 4=>_MD_RATING);

		$html = '<span>'. _MD_SORTBY ."</span>\n";
		for ($i=0; $i<count($field_arr); $i++) {
			$temp_img = $field_arr[$i] .'_img';
			if (! empty($$temp_img)) {
				$temp_order = strtolower($order) == 'desc' ? 'ASC': 'DESC';
			} else {
				$temp_order = 'ASC';
			}
			$html .= "<a href='". $this->makeUrl($controller, $method, 
								$args_plus1 + $args_plus2 + array('f' => $field_arr[$i], 'ord' => $temp_order) ) ."'>
					". $title_arr[$i] . $$temp_img ."</a>\n";
		}

		return $html;
	}

	function convertOrder($orderby) 
	{
		if ($orderby == "hits ASC")    return _MD_POPULARITYLTOM;
		if ($orderby == "hits DESC")   return _MD_POPULARITYMTOL;
		if ($orderby == "title ASC")   return _MD_TITLEATOZ;
		if ($orderby == "title DESC")  return _MD_TITLEZTOA;
		if ($orderby == "date ASC")    return _MD_DATEOLD;
		if ($orderby == "date DESC")   return _MD_DATENEW;
		if ($orderby == "rating ASC")  return _MD_RATINGLTOH;
		if ($orderby == "rating DESC") return _MD_RATINGHTOL;
		if ($orderby == "access ASC")  return _MD_ACCESS_ASC;
		if ($orderby == "access DESC") return _MD_ACCESS_DESC;
	}

	function _new_link_check($time, $status) 
	{
		$count = 7;//TODO 7days
		$new = 0;
		$startdate = (time()-(86400 * $count));
		if ($startdate < $time) {
			$new = intval($status);
		}
		return $new;
	}

	function _pop_check($hits) 
	{
		if ($hits >= $this->module_config['popular']) {
			return TRUE;
		}
		return FALSE;
	}

	function getUnameFromUid( $uid )
	{
		global $xoopsConfig ;

		if( $uid > 0 ) {
			$member_handler =& xoops_gethandler('member') ;
			$poster =& $member_handler->getUser($uid) ;
			if( is_object( $poster ) ) {
				$name = htmlspecialchars( $poster->uname(), ENT_QUOTES, _CHARSET) ;
			} else {
				$name = htmlspecialchars($xoopsConfig['anonymous'], ENT_QUOTES, _CHARSET) ;
			}
		} else {
			$name = htmlspecialchars($xoopsConfig['anonymous'], ENT_QUOTES, _CHARSET) ;
		}
		return $name ;
	}

	function makeDateSelector($date = NULL)// $data : UNIXTIMESTAMP
	{
		$date = !empty($date) ? $date: time();
		$d = getdate($date) ;

		$select_tag = '<select name="%s">%s</select>';
		$option_tag = '<option %s>%u</option>';
		$selected   = 'selected="SELECTED"';

		//YEAR
		$dateselector = $temp_option = '' ;
		for($i=$d['year']+2; $i>=$d['year']-2; $i--){
			$sel = ( $i==$d['year'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel, $i);
		}
		$dateselector .= sprintf( $select_tag , 'year' , $temp_option );
		//MONTH
		$temp_option = '' ;
		for($i=1;$i<=12;$i++){
			$sel = ( $i==$d['mon'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel, $i);
		}
		$dateselector .= sprintf( $select_tag , 'month' , $temp_option );
		//DAY
		$temp_option = '' ;
		for($i=1;$i<=31;$i++){
			$sel = ( $i==$d['mday'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel, $i);
		}
		$dateselector .= sprintf( $select_tag , 'day' , $temp_option ) . "&nbsp;";
		//----------------------
		if ($this->is_mobile) {
			$dateselector .= '<br />';
		}
		//----------------------
		//HOURS
		$temp_option = '' ;
		for($i=0;$i<24;$i++){
			$sel = ( $i==$d['hours'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel, $i);
		}
		$dateselector .= sprintf( $select_tag , 'hours' , $temp_option ) . ":";
		//MINUTES
		$temp_option = '' ;
		for($i=0;$i<60;$i++){
			$sel = ( $i==$d['minutes'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel,$i);
		}
		$dateselector .= sprintf( $select_tag , 'minutes' , $temp_option ) . ":";
		//SECONDS
		$temp_option = '' ;
		for($i=0;$i<60;$i++){
			$sel = ( $i==$d['seconds'] ) ? $selected : '' ;
			$temp_option .= sprintf($option_tag , $sel,$i);
		}
		$dateselector .= sprintf( $select_tag , 'seconds' , $temp_option );

		return $dateselector;
	}

	function _get_make_date()
	{
		$date='';

		if (isset($_POST['hours']) AND isset($_POST['minutes']) AND isset($_POST['seconds']) 
				AND isset($_POST['month']) AND isset($_POST['day']) AND isset($_POST['year'])) 
		{
			$hours   = intval($_POST['hours']);
			$minutes = intval($_POST['minutes']);
			$seconds = intval($_POST['seconds']);
			$month   = intval($_POST['month']);
			$day     = intval($_POST['day']);
			$year    = intval($_POST['year']);
			if ($hours < 0 OR $hours >= 24) $hours = 0;
			if ($minutes < 0 OR $minutes >= 60) $minutes = 0;
			if ($seconds < 0 OR $seconds >= 60) $seconds = 0;
			if ($month < 1 OR $month > 12) $month = 1;
			if (in_array($month,array(1,3,5,7,8,10,12))) {
				if ($day < 1 OR $day > 31) $day = 1;
			} else if ($month == 2) {
				if ($year%4 == 0) {
					if ($year%100 == 0) {
						if ($day < 1 OR $day > 28) $day = 1;
					} else {
						if ($day < 1 OR $day > 29) $day = 1;
					}
				} else {
					if ($day < 1 OR $day > 28) $day = 1;
				}
			} else {
				if ($day < 1 OR $day > 30) $day = 1;
			}
			if($year < 2000) $year = 2000;//TODO
			$date = mktime($hours, $minutes, $seconds, $month, $day, $year) ;
		} else {
			$date = time();
		}

		return $date ;
	}

	function _clear_data()
	{
		//links
		$items = array(	'lid', 'cid', 'title', 'url', 'murl', 
						'submitter', 'guestname', 'status', 'date', 'hits', 
						'rating', 'votes', 'adult', 'ip', 'access');
		foreach ($items as $item) {
			unset($this->save_items[$item]);
		}
		//text
		unset($this->save_description);
	}

	function _get_POST_data()
	{
		$this->_clear_data();
		$this->save_items['cid'] = array_unique($_POST['cid']);
		$this->save_items['title'] = empty($_POST['title']) ? '': $this->stripSlashesGPC(trim($_POST['title']));
		$this->save_items['url'] = ( empty($_POST['url']) || $_POST['url']=='http://' || strlen($_POST['url'])<=8 ) ? '': $this->stripSlashesGPC(trim($_POST['url']));
		$this->save_items['murl'] = ( empty($_POST['murl']) || $_POST['murl']=='http://' || strlen($_POST['murl'])<=8 ) ? '': $this->stripSlashesGPC(trim($_POST['murl']));
		$this->save_description = empty($_POST['desc']) ? '': $this->stripSlashesGPC($_POST['desc']);
		$this->save_items['guestname'] = empty($_POST['guestname']) ? '': $this->stripSlashesGPC($_POST['guestname']);
		$this->save_items['adult'] = isset($_POST['adult']) ? intval($_POST['adult']) : 0 ;
		//DATE
		if ( isset($_POST['age']) && $_POST['age']==1 ) {
			if (isset($_POST['make_regidate']) AND $_POST['make_regidate'] == 1) {
				$this->save_items['date'] = $this->_get_make_date();
			} else {
				$this->save_items['date'] = time();
			}
		}
	}

	function _basic_post_data_check($action = 'insert', $lid = NULL)
	{
		//Return URL
		$return_controller = 'submit';
		$return_args = array();
		if ($action == 'update') {
			$return_controller = 'edit';
			$return_args['lid'] = $lid;
		}
		$redirect_url = $this->makeUrl($return_controller, 'form', $return_args);
	
		//basic check
		if( empty($this->save_items['title']) ){
			$this->linksRedirectHeader($redirect_url, 3, _MD_SITETITLE.' '._MD_SUBMIT_ALERT);
			exit();
		}
		if( empty($this->save_items['url']) && empty($this->save_items['murl']) ){
			$this->linksRedirectHeader($redirect_url, 3, _MD_SITEURL.' or '._MD_MOBILE_SITEURL.' '._MD_SUBMIT_ALERT);
			exit();
		}
		//URL control code check
		if( ! $this->linksUrlCCCheck($this->save_items['url']) || ! $this->linksUrlCCCheck($this->save_items['murl']) ){
			$this->linksRedirectHeader( $redirect_url, 3, _MD_URL_WRONG ) ;
			exit();
		}
		//Check URL
		$db =& Database::getInstance();
		if( !empty($this->save_items['url']) ){
			$check_url = FALSE;
			if ($action == 'update') {
				$sql = $db->query("SELECT url FROM ". $this->table_links ." WHERE lid=$lid");
				list( $now_url ) = $db->fetchRow($sql);
				if( strtolower($this->save_items['url']) != strtolower($now_url) ){
					$check_url = TRUE;
				}
			}
			if ($action == 'insert' OR $check_url) {
				$sql = $db->query("SELECT count(*) FROM ". $this->table_links ." WHERE url='". mysql_real_escape_string($this->save_items['url']) ."'");
				list($numrows) = $db->fetchRow($sql);
				if ( $numrows > 0 ) {
					$this->linksRedirectHeader($redirect_url, 3, _MD_ERROREXIST );
					exit();
				}

				//URL check
				$statuscode = check_URI($this->save_items['url'], TRUE);
				//if (! in_array($statuscode, array(200, 201, 202))) {//TODO
				if (200 != intval($statuscode/100)*100) {//TODO
					if ($action == 'insert') {
						$_SESSION[$this->mydirname] = array( 
								'site_title'=>$this->save_items['title'] , 'site_url'=>$this->save_items['url'] , 'murl'=>$this->save_items['murl'] , 
								'desc'=>$this->save_description , 'guestname'=>$this->save_items['guestname'] , 'adult'=>$this->save_items['adult'] 
							);
					}
					$this->linksRedirectHeader($redirect_url, 3, _MD_NO_ADDRESS.' (PC) - '.intval($statuscode) );
					exit();
				}
				$this->status_code = " (PC: $statuscode)";
			}
		}
		if( !empty($murl) ){
			$check_murl = FALSE;
			if ($action == 'update') {
				$sql = $db->query("SELECT murl FROM ". $this->table_links ." WHERE lid=$lid");
				list( $now_murl ) = $db->fetchRow($sql);
				if ( strtolower($this->save_items['murl']) != strtolower($now_murl) ) {
					$check_murl = TRUE;
				}
			}
			if ($action == 'insert' OR $check_murl) {
				$sql = $db->query("SELECT count(*) FROM ". $this->table_links ." WHERE murl='". mysql_real_escape_string($this->save_items['murl']) ."'");
				list($numrows) = $db->fetchRow($sql);
				if ( $numrows > 0 ) {
					$this->linksRedirectHeader($redirect_url, 3 , _MD_ERROREXIST );
					exit();
				}

				//URL check
				$statuscode = check_URI($this->save_items['murl'], TRUE);
				//	if (! in_array($statuscode, array(200, 201, 202, 403))) {//TODO
				if (200 != intval($statuscode/100)*100 || $statuscode != 403) {//TODO
					if ($action == 'insert') {
						$_SESSION[$this->mydirname] = array( 
								'site_title'=>$this->save_items['title'] , 'site_url'=>$this->save_items['url'] , 'murl'=>$this->save_items['murl'] , 
								'desc'=>$this->desc , 'guestname'=>$this->save_items['guestname'] , 'adult'=>$this->save_items['adult'] 
							);
			 		}
					$this->linksRedirectHeader($redirect_url, 3, _MD_NO_ADDRESS.' (MOBILE) - '.intval($statuscode) );
					exit();
				}
				$this->status_code .= " (Mobile: $statuscode)";
			}
		}
	}

	function _for_save_cid_data($cid)
	{
		sort( $cid , SORT_NUMERIC ) ;
		if( $cid[0]==0 ) $cid = array_splice($cid,1,count($cid)-1);
		if(count($cid) == 0){
			$this->linksRedirectHeader($this->baseUrl(TRUE), 3, _MD_CATEGORY.' '._MD_SUBMIT_ALERT);
			exit();
		}
		$cid = array_map('intval', $cid);
		$cidtext = '[' .implode('][',$cid). ']';
		
		return $cidtext;
	}

	function _cid_array_from_cid_text($cid_text)
	{
		$cid = substr_replace($cid_text,'',0,1) ;
		$cid = substr_replace($cid,'',strlen($cid)-1,1);
		$cids = explode('][',$cid);
		$cids = array_map('intval',$cids) ;

		$sort_cid_arr = array();
		foreach( $this->allkeycid as $c ){
		  if(in_array($c , $cids)) $sort_cid_arr[] = $c ;
		}
		
		return $sort_cid_arr;
	}

	function _check_cache_file($lid, $url, $regi_date)
	{
		$cache_time = $this->screenshot_cache_time * 24 * 60 * 60;//from day to seconds
		$capture_file = $this->cache_dir .'/'. $lid .'.jpg';
		if (file_exists($capture_file)) {
			if ($this->single_view AND $file_timestamp = filemtime($capture_file)) {
				if ($file_timestamp +$cache_time < time()) {
					if ($this->_copy_capture_file($lid, $url, $regi_date, TRUE)) {
						return TRUE;
					}
				} else {
					return TRUE;
				}
			} else {
				return TRUE;
			}
		} else {
			if (! $this->block_capture) {
				if ($this->_copy_capture_file($lid, $url, $regi_date)) {
					return TRUE;
				}
			}
		}
		return FALSE;
	}

	function _copy_capture_file($lid, $url, $regi_date, $force = FALSE)
	{
		require_once XOOPS_ROOT_PATH .'/class/snoopy.php' ;

		$snoopy = New Snoopy;

		if ($force == TRUE) {
			$force_query = 'http://capture.heartrails.com/api/force_capture/?'. $url;
			$snoopy->fetch($force_query);
			sleep(1);
		}

		$query = 'http://capture.heartrails.com/api/get_status/?'. $url;
		@$snoopy->fetch($query);
		$json = $snoopy->results;

		if (empty($json)) {
			return FALSE;
		}

		$json = str_replace(array('{','}','"'), '', $json);
		$json_arr = explode(',', $json);

		$status = '';
		for ($i=0; $i<count($json_arr); $i++) {
			list($key, $val) = explode(':', $json_arr[$i]);
			if(trim($key) == 'status') {
				$status = trim($val);
				break;
			}
		}

		if ($status == 'done') {
			return $this->_force_copy($lid, $url);
		}

		return FALSE;
	}

	function _force_copy($lid, $url)
	{
		require_once XOOPS_ROOT_PATH .'/class/snoopy.php' ;

		if (! empty($url)) {
			if (! preg_match("/^http[s]{0,1}:\/\//i", $url)) {
				return FALSE;
			}

			$copy_saki = $this->cache_dir .'/'. $lid .'.jpg';

			if (file_exists($copy_saki)) {
				unlink($copy_saki);
			}

			$copy_moto = 'http://capture.heartrails.com/128x128/shadow?'. $url;

			$snoopy = New Snoopy ;
			@$snoopy->fetch($copy_moto) ;
			if (@$snoopy->response_code) {
				$res = explode(' ', $snoopy->response_code);
			}
			if (isset($res[1])) $status_code = intval($res[1]) ;
			if ($status_code == 200) {
				$fp = fopen($copy_saki, 'wb');
				fwrite($fp, $snoopy->results);
				fclose($fp);
				return TRUE;
			} else {
				return FALSE;
			}
		}

		return FALSE;
	}

	function hitsCounterUp($lid)
	{
			$db =& Database::getInstance();
			$sql = sprintf("UPDATE %s SET hits=hits+1 WHERE lid=%u AND status>0", $this->table_links , $lid);
			$db->queryF($sql);
	}

	function accessCounterUp($lid)
	{
		$access_array = array();
		if (isset($_SESSION[$this->mydirname . '_access_lid_array'])) {
			$access_array = unserialize($_SESSION[$this->mydirname . '_access_lid_array']);
		}
		if (is_array($access_array) && !in_array($lid, $access_array)) {
			$access_array[] = $lid;
			$_SESSION[$this->mydirname . '_access_lid_array'] = serialize($access_array);
			$db =& Database::getInstance();
			$sql = sprintf("UPDATE %s SET access=access+1 WHERE lid=%u AND status>0", $this->table_links , $lid);
			$db->queryF($sql);
			return TRUE;
		}
		return FALSE;
	}

	//Control Code Check
	function linksUrlCCCheck($text)
	{
		$rtn = TRUE;
		if (preg_match("/[\\x0-\\x1f]|[\\x7f]/", $text)) {
	//	if (preg_match("/[\\0-\\31]/", $text)) {
			$rtn = FALSE;
		}
		return $rtn;
	}

	function stripSlashesGPC($string)
	{
		if (get_magic_quotes_gpc()) {
			$string = stripslashes($string);
		}
		return $string;
	}

	function basicPostCheck($ticket_name, $spam_check = TRUE)
	{
		global $xoopsUser;

		//GTicket Check
		if (! $GLOBALS['xoopsGTicket']->check(TRUE , $ticket_name)) {
			$this->linksRedirectHeader($this->baseUrl(TRUE), 3, $GLOBALS['xoopsGTicket']->getErrors());
			exit();
		}

		// Check K-TAI
		if ($this->is_mobile) {
			if (defined('HYP_K_TAI_RENDER') && HYP_K_TAI_RENDER) {
				$HypCommonPreLoad = new HypCommonPreLoad();
				$HypKTaiRender = new HypKTaiRender();
				if ($HypCommonPreLoad->k_tai_conf['noCheckIpRange'] == 1 ) {
					return;
				} else if ($HypKTaiRender->checkIp($_SERVER['REMOTE_ADDR'], $HypKTaiRender->vars['ua']['carrier'])) {
					return;
				} else {
					$this->linksRedirectHeader($this->baseUrl(TRUE), 3, _MD_NOT_MOBILE);
					exit();
				}
			} else {
				global $xoopsTpl;
				if ($xoopsTpl->_tpl_vars['wizmobile_ismobile']) {
					return;
				}
			}
		}

		//SPAM Check
		if(!is_object($xoopsUser) && !empty($_POST['CP']) && $spam_check){
			$this->linksRedirectHeader($this->baseUrl(TRUE), 3, _MD_NEED_JS);
			exit();
		}

		return;
	}

	function linksRedirectHeader($url, $seconds = 2, $message = '')
	{
		//Delegate
		if (defined('XOOPS_CUBE_LEGACY')) {
			if ($this->delegate_method != NULL) {
				$pm = $this->is_mobile ? 'Mobile': 'Pc';
				$delegate_name = ucfirst(strtolower($this->mydirname)) .'.'. ucfirst(strtolower($this->controller_name)) 
									.'.'. ucfirst(strtolower($this->delegate_method)) .'.'. $pm;
			} else {
				$delegate_name = $this->delegate_name;
			}
			XCube_DelegateUtils::call($delegate_name .'.'. 'BeforeRedirect', new XCube_Ref($this));
		}

		if (preg_match("/[\\x0-\\x1f]|[\\x7f]/", $url) || preg_match("/^(javascript|vbscript|about):/i", $url)) {
	//	if (preg_match("/[\\0-\\31]/", $url) || preg_match("/^(javascript|vbscript|about):/i", $url)) {
			$url = XOOPS_URL;
		}
		if (defined('LINKS_ADMIN_AREA') || $this->module_config['redirect_type'] == 1 || strstr($url, 'user.php') || $this->is_mobile) {
			redirect_header($url, $seconds, $message);
			exit;
		} else {
			if (! headers_sent()) {
				$_SESSION[$this->mydirname. '_my_redirect_message'] = $message ;
				header("Location: ". strtr(preg_replace('/[&]amp;/i', '&', $url),"\r\n\0","   ")) ;
				exit ;
			} else {
				die('Headers Already Sent');
			}
		}
	}

	/** View
	 *
	**/
	function view($template = NULL, $data = NULL)
	{
		global $xoopsOption, $xoopsTpl, $xoopsConfig, $xoopsUser, $xoopsUserIsAdmin, $xoopsLogger, $xoopsModule, $xoopsConfigSearch;

		$xoops_pagetitle = '';
		if (defined('XOOPS_CUBE_LEGACY')) {
			//Delegate
			if ($this->delegate_method != NULL) {
				$pm = $this->is_mobile ? 'Mobile': 'Pc';
				$delegate_name = ucfirst(strtolower($this->mydirname)) .'.'. ucfirst(strtolower($this->controller_name)) 
									.'.'. ucfirst(strtolower($this->delegate_method)) .'.'. $pm;
			} else {
				$delegate_name = $this->delegate_name;
			}
			XCube_DelegateUtils::call($delegate_name .'.'. 'BeforeView', new XCube_Ref($this), new XCube_Ref($data));

			// FOR url_approach == 3
			if ($this->module_config['url_approach'] == 3) {
				require_once XOOPS_MODULE_PATH ."/legacy/kernel/Legacy_Module.class.php";
				$root =& XCube_Root::getSingleton();
				$xoopsModule = $this->getXoopsModule();
				$root->mContext->mModule = new Legacy_ModuleAdapter($xoopsModule);
				$root->mContext->mModule->mXoopsModule =& $xoopsModule;
				$root->mContext->mXoopsModule =& $xoopsModule;
				$xoops_pagetitle = htmlspecialchars($this->module_name, ENT_QUOTES, _CHARSET);
			}
		}

		$xoopsOption['template_main'] = $template;
		include XOOPS_ROOT_PATH ."/header.php";
		$xoopsTpl->assign($this->_basic_assign());
		$xoopsTpl->assign($data);

		// smarty plugin
		$xoopsTpl->register_function('my_make_uri', 'smarty_function_my_make_uri');
		$xoopsTpl->plugins_dir[] = realpath(dirname(__FILE__)) . '/../class/smartyplugins';
	/*	if (
			!empty($this->module_config['comment_dirname']) && !empty($this->module_config['comment_forum_id']) &&
			!file_exists(XOOPS_ROOT_PATH .'/class/smarty/plugins/function.d3comment.php') && 
			!file_exists(XOOPS_TRUST_PATH .'/libs/smartyplugins/function.d3comment.php')
		) {
			require_once realpath(dirname(__FILE__)) . '/../class/smartyplugins/function.d3comment.php';
			$xoopsTpl->register_function('d3comment', 'smarty_function_d3comment');
		}
		if (
			($this->controller_name == 'submit' || $this->controller_name == 'edit') && 
			(!file_exists(XOOPS_ROOT_PATH .'/class/smarty/plugins/function.xoopsdhtmltarea.php') || 
			!file_exists(XOOPS_TRUST_PATH .'/libs/smartyplugins/function.xoopsdhtmltarea.php'))
		) {
			require_once realpath(dirname(__FILE__)) . '/../class/smartyplugins/function.xoopsdhtmltarea.php';
			$xoopsTpl->register_function('xoopsdhtmltarea', 'smarty_function_xoopsdhtmltarea');
		}*/

		if (!empty($xoops_pagetitle)) {
			$xoopsTpl->assign(array('xoops_pagetitle' => $xoops_pagetitle));
		}
		include XOOPS_ROOT_PATH .'/footer.php';
	}

	function adminView($template = NULL, $data = NULL)
	{
		require_once XOOPS_ROOT_PATH.'/class/template.php';
		$tpl = new XoopsTpl() ;

		xoops_cp_header();
		// for mymenu.php (
		$xoopsModule    = $this->getXoopsModule();
		$mydirname      = $this->mydirname;
		$mytrustdirname = $this->mytrustdirname;
		// );
		include $this->mytrustdirpath .'/admin/mymenu.php';
	//	if (!defined('XOOPS_CUBE_LEGACY')) {
			$tpl->register_function('my_make_uri', 'smarty_function_my_make_uri');
	//	}
		$tpl->assign($this->_basic_assign(TRUE));
		$tpl->assign($data);
		$tpl->display('db:'. $template);
		xoops_cp_footer();
	}

	function setDbModel($class_name = NULL)
	{
		if (!file_exists($this->mytrustdirpath .'/class/db_'. strtolower($class_name) .'.class.php')) {
			return FALSE;
		}
		require_once $this->mytrustdirpath .'/class/db_'. strtolower($class_name) .'.class.php';

		if (! class_exists(ucfirst($class_name))) {
			return FALSE;
		}

		$obj = new $class_name($this->mydirname);
		$obj->setLinks($this);
		return $obj;
	}

	// Return to Javascript
	function returnEnc($rtn)
	{
		header("Content-Type: text/javascript; charset=utf-8");
		if (function_exists('mb_http_output') && function_exists('mb_convert_encoding')) {
			mb_http_output('pass');
			return mb_convert_encoding($rtn, 'UTF-8', 'auto');
		} else {
			return $rtn;
		}
	}

	function screenShotServiceON()
	{
		$this->_screen_Shot_Service_Check(TRUE);
	}

	function baseUrl($suffix = FALSE)// TODO not suffix
	{
		$uri = XOOPS_URL . '/';

		if ($this->module_config['url_approach'] == 3) {
			$uri .= $this->mydirname . '/' ;
		} else {
			$uri .= 'modules/' . $this->mydirname . '/' ;
		}

		if ($this->module_config['url_approach'] == 1 && $suffix != TRUE) {
			$uri .= 'index.php';
		}

		return $uri;
	}

	function makeUrl($controller = 'index', $method = 'index', $args = array(), $ref = TRUE)
	{
		$uri = $this->baseUrl( ($controller != NULL || $method != NULL) ? FALSE: TRUE );

		if ($this->module_config['url_approach'] > 0) {
			//segment approach
		/*	if ($this->module_config['url_approach'] == 1) {
				$uri .= '/';
			}*/

			$uri = rtrim($uri, '/');
			if ($controller != 'index') {
				$uri .= '/' . $controller;
			}

			if ($method != 'index') {
				$uri .= '/' . $method;
			}

			foreach ($args as $k => $v) {
				$uri .= '/'. $v ;
			}

			if (!empty($this->module_config['url_suffix'])) {
				$uri .= $this->module_config['url_suffix'];
			}

		} else {
			//query approach
			$amp = ($ref == TRUE) ? '&amp;': '&';
			$uri .= 'index.php?';

			if ($controller != 'index') {
				$uri .= 'c='. $controller;
			}

		//	if ($controller != 'index' || $method != 'index' /*|| $p_val1 != '' ||  $p_val2 != '' ||  $p_val3 != ''*/) {
		//		$uri .= '?c=' . $controller;
		//	}

			if ($method != 'index' /*|| $p_val1 != '' ||  $p_val2 != '' ||  $p_val3 != ''*/) {
				$joint = (substr($uri, -1)=='?') ? '': $amp; 
				$uri .= $joint . 'm=' . $method;
			}

			foreach ($args as $k => $v) {
				$uri .= $amp . $k . '=' . $v ;
			}

		}

		return $uri;
	}

	/** Bread crumbs
	 *
	**/
	function breadcrumbs()
	{
		$this->bread[] = array('name'=> $this->module_name, 'url' => $this->baseUrl(TRUE));

		$bcname = array(
			'submit'      => _MD_SUBMITLINK,
			'future'      => _MD_FUTURE,
			'adult'       => _MD_ADULTS,
			'broken'      => _MD_REPORTBROKEN,
			'rating'      => _MD_RATETHISSITE,
			'edit'        => _MD_MODIFY,
			'request'     => _MD_REQUESTMOD,
			'bookmarklet' => _MD_BOOKMARKLET,
		);

		if (isset($bcname[$this->controller_name])) {
			$this->bread[] = array('name' => $bcname[$this->controller_name]);
		}
	}

	function getBreadcrumbs()
	{
		return $this->bread;
	}

	function setControllerName($controllerName)
	{
		$this->controller_name = $controllerName;
	}

	function getXoopsModule()
	{
		$module_handler =& xoops_gethandler('module');
		$xoopsModule =& $module_handler->getByDirname($this->mydirname);
		return $xoopsModule;
	}

	function getTemplatePrefix()
	{
		$mobile_page = array('index', 'rating', 'ranking', 'adult', 'broken', 'category', 'edit', 'future', 'request', 'submit', 'visit');

		$template_prefix  = $this->mydirname;
		if ($this->is_mobile && in_array($this->controller_name, $mobile_page)) {
			$template_prefix .= '_mobile';
		}

		return $template_prefix;
	}

	function _basic_assign($admin_view = FALSE)
	{
		global $xoopsTpl;

		$message = '';
		if (isset($_SESSION[$this->mydirname. '_my_redirect_message'])) {
			$message = nl2br(htmlspecialchars($_SESSION[$this->mydirname. '_my_redirect_message'], ENT_QUOTES, _CHARSET));
			unset($_SESSION[$this->mydirname. '_my_redirect_message']);
		}

		$xoops_module_header = '';
		if ($admin_view === FALSE) {
			$xoops_module_header = $xoopsTpl->get_template_vars('xoops_module_header');
			if (! $this->is_mobile) {
				if (!strstr($xoops_module_header, "jquery")) {
					$xoops_module_header .= '
						<script src="http://www.google.com/jsapi" type="text/javascript"></script>
						<script type="text/javascript">
							google.load("jquery","1");
						</script>';
				}
				$xoops_module_header .= '
					<script type="text/javascript" src="'. $this->myurl .'/js/script.js"></script>
					<link rel="stylesheet" type="text/css" media="all" href="'. $this->myurl .'/css/style.css" />';
			}
		}
/*
		$comment_plugin = FALSE;
		if (! empty($this->module_config['comment_dirname']) && ! empty($this->module_config['comment_forum_id'])) {
			if (file_exists(XOOPS_ROOT_PATH .'/class/smarty/plugins/function.d3comment.php') || 
				file_exists(XOOPS_TRUST_PATH .'/libs/smartyplugins/function.d3comment.php')) 
			{
				$comment_plugin = TRUE;
			}
		}
*/
		// TODO 
		$links_Form_ON = FALSE;
		$gticket_arr = array();
		if (in_array($this->controller_name, array('index','category'))) {
			$links_Form_ON = TRUE;
			$gticket_arr['broken']  = $GLOBALS['xoopsGTicket']->issue(__LINE__, 1800, 'links_broken');
			$gticket_arr['request'] = $GLOBALS['xoopsGTicket']->issue(__LINE__, 1800, 'links_request');
			$gticket_arr['rating']  = $GLOBALS['xoopsGTicket']->issue(__LINE__, 1800, 'links_rating');
		}

		// for display type : table options
		$table_cols = empty($this->module_config['table_cols']) ? 3 : intval($this->module_config['table_cols']);

		$basic_assign = array(
			'myurl'                 => $this->myurl,
			'mydirname'             => $this->mydirname,
			'post_perm'             => $this->post_perm,
			'post_approval'         => $this->post_approval,
			'edit_perm'             => $this->edit_perm,
			'edit_approval'         => $this->edit_approval,
			'del_perm'              => $this->del_perm,
			'del_approval'          => $this->del_approval,
			'request_perm'          => $this->request_perm,
			'catimgpath'            => htmlspecialchars(links_urlCheckReplace($this->module_config['categoryicon_path']), ENT_QUOTES, _CHARSET),
			'uid'                   => $this->uid,
			'uname'                 => $this->uname,
			'realname'              => $this->realname,
			'isadmin'               => $this->isadmin,
			'xoops_breadcrumbs'     => $this->bread,
			'category_selector'     => $this->category_selector,
			'is_mobile'             => $this->is_mobile,
			'screen_shot'           => $this->screen_shot,
			'screenshotservice'     => $this->screen_shot_service ,
			'screenshot_cache_time' => $this->screenshot_cache_time,
			'cache_url'             => $this->cache_url ,
			'allcid'                => $this->allcid ,
			'comment_dirname'       => htmlspecialchars($this->module_config['comment_dirname'], ENT_QUOTES, _CHARSET),
			'comment_forum_id'      => intval($this->module_config['comment_forum_id']),
		//	'comment_plugin'        => $comment_plugin,
			'rating_type'           => intval($this->module_config['rating_type']),
		//	'xoops_module_header'   => $xoops_module_header,
			'redirect_message'      => $message,
			'c_tree_controller'     => 'category',
			'c_tree_method'         => 'index',
			'links_Form_ON'         => $links_Form_ON,
			'gticket_arr'           => $gticket_arr,
			'display_type'          => intval($this->module_config['display_type']), //0:LIST, 1:TABLE
			'table_cols'            => $table_cols,
			'col_width'             => intval(100/$table_cols),
			'uri_options'           => $this->uri_option_arr,
		);
		if (!empty($xoops_module_header)) {
			$basic_assign['xoops_module_header'] = $xoops_module_header;
		}

		return $basic_assign;
	}

}
